#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"

using namespace log_ns;

// 客户端在未来一定要知道服务器的ip port
int main(int argc, char* args[]) {
    if (argc != 3) {
        LOG(ERROR, "please input the -> ./client、ip and port\n");
        return 0;
    }
    // 获取 ip 和 port 以及 socket
    uint16_t server_port = std::stoi(args[2]);
    std::string server_ip = args[1];

    int local_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (local_socket < 0) {
        LOG(FATAL, "Create socket fail\n");
        exit(0);
    }
    LOG(INFO, "Create socket success\n");

    // 对于client的端口号，一般不让用户自己设定，而是让client OS随机选择
    // client需要bind自己的ip和port，但是client不需要显示的bind自己的ip、port
    // client在首次向服务器发送数据的时候，OS会自动给client bind上它自己的ip、port


    // 绑定服务器信息
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    socklen_t len = sizeof(server);
    server.sin_family = AF_INET;
    server.sin_port = htons(server_port);
    server.sin_addr.s_addr = inet_addr(server_ip.c_str());

    // 客户端的ip和port不需要指定，自己会给出
    // 在这里就可以发送消息了
    while (true) {
        std::string info;
        std::cout << "Please input the info: ";
        std::getline(std::cin, info);
        if (info.size() > 0) {
            // 将消息发送出去
            int num = sendto(local_socket, info.c_str(), info.size(), 0, (struct sockaddr*)&server, len);
            if (num > 0) {
                // 收消息
                struct sockaddr_in temp;

                char buff[1024];
                int recvlen = recvfrom(local_socket, buff, sizeof(buff) - 1, 0, (struct sockaddr*)&temp, &len);
                if (recvlen > 0) {
                    buff[recvlen] = 0;
                    std::cout << buff << std::endl;
                } else {
                    break;
                }
            }
        } else {
            break;
        }
    }

    close(local_socket);
    return 0;
}